package org.loong.crypto.service.software.provider.asymmetric.sm2;

import java.security.interfaces.ECPrivateKey;
import java.util.Objects;

import org.loong.crypto.common.exception.CryptoException;
import org.loong.crypto.common.exception.InvalidKeyException;
import org.loong.crypto.core.algorithm.CipherAlgorithm;
import org.loong.crypto.core.utils.ECKeyUtils;
import org.loong.crypto.service.core.provider.Decrypter;
import org.loong.crypto.service.core.provider.impl.SM2CipherProvider;

import cn.hutool.crypto.asymmetric.SM2;

/**
 * SM2 decrypt of data.
 */
public class SM2Decrypter extends SM2CipherProvider implements Decrypter {

    /**
     * The private key.
     */
    private ECPrivateKey privateKey;

    /**
     * Creates a new signer.
     *
     * @param keyBytes the private key bytes. Must not be {@code null}.
     */
    public SM2Decrypter(final byte[] keyBytes) {
        this(ECKeyUtils.toECPrivateKey(keyBytes));
    }

    /**
     * Creates a new signer.
     *
     * @param privateKey the private key. Must not be {@code null}.
     */
    public SM2Decrypter(final ECPrivateKey privateKey) {
        if (Objects.isNull(privateKey)) {
            throw new InvalidKeyException("The sm2 private key must not be null.");
        }

        if (!"EC".equalsIgnoreCase(privateKey.getAlgorithm())) {
            throw new InvalidKeyException("The private key algorithm must be EC.");
        }

        this.privateKey = privateKey;
    }

    @Override
    public byte[] decrypt(CipherAlgorithm algorithm, byte[] cipherText) throws CryptoException {
        try {
            SM2 sm2 = new SM2(privateKey, null);
            return sm2.decrypt(cipherText);
        } catch (cn.hutool.crypto.CryptoException e) {
            throw new CryptoException("SM2 decrypt exception: " + e.getMessage(), e);
        }
    }
}
